package thread.waitnotifypackage;

import java.util.Random;

// 1000米多个运动员同时开跑，输出每个运动员耗费时间
public class Demo1 {

    private static final Object object = new Object();

    public static void main(String[] args) {
        new Thread(new Runner("A")).start();
        new Thread(new Runner("B")).start();
        new Thread(new Runner("C")).start();
        // 模拟321准备阶段。
        // 这个地方一定要休眠，否则还没等到三个线程wait就notify了，这样就永远获取不到锁了。
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        synchronized (object) {
            System.out.println("马上唤醒三个线程");
            object.notifyAll();
        }
    }

    static class Runner implements Runnable {
        private final String threadName;

        public Runner(String a) {
            threadName = a;
        }

        @Override
        public void run() {
            synchronized (object) {
                try {
                    System.out.println(threadName + "马上要wait了");
                    object.wait(); // 三个线程都停在这，主线程唤醒三个线程
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("运动员：" + threadName + "开始");

                Long startTime = System.currentTimeMillis();
                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Long endTime = System.currentTimeMillis();
                System.out.println("运动员：" + threadName + "耗时：" + (endTime - startTime));
                object.notifyAll();
            }
        }
    }

}

// wait 和 notify 一定要放在 synchronized 里使用